#include "lock.h"
#include "sched.h"
#include "syscall.h"
mutex_lock_t kernel_lock[32];
void spin_lock_init(spin_lock_t *lock)
{
    lock->status = UNLOCKED;
}

void spin_lock_acquire(spin_lock_t *lock)
{
    while (LOCKED == lock->status)
    {
    };
    lock->status = LOCKED;
}

void spin_lock_release(spin_lock_t *lock)
{
    lock->status = UNLOCKED;
}

void do_mutex_lock_init(mutex_lock_t *lock)
{
     lock->status = UNLOCKED;
     queue_init(&lock->block_queue);
}

void do_mutex_lock_acquire(mutex_lock_t *lock)
{
    while(lock->status == LOCKED)
        {
            do_block(&lock->block_queue);
            do_scheduler();
        }
    lock->status = LOCKED;
    current_running->lock[current_running->lock_count++] = lock;
}

void do_mutex_lock_release(mutex_lock_t *lock)
{
    int i = 0 ;
    for(i = 0 ; i < current_running->lock_count; i++)
    {
        if(current_running->lock[i] == lock)
            break;
    }
    for( ; i < current_running->lock_count ; i++)
    {
        current_running->lock[i] = current_running->lock[i + 1];
    }
    current_running->lock_count--;
    if (!queue_is_empty(&lock->block_queue))
    {
        do_unblock_one(&lock->block_queue);
    }

    lock->status = UNLOCKED;
    //do_scheduler();
}
int get_lock_id(int key)
{
    return key % 32;
}
int do_op_lock(int id,int op)
{
    if(op == BINSEM_OP_LOCK)
        do_mutex_lock_acquire(&kernel_lock[id]);
    else if (op == BINSEM_OP_UNLOCK)
        do_mutex_lock_release(&kernel_lock[id]);
    else
        return 0;
}
